package com.korustar.autumnal.codemodel;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import com.korustar.autumnal.OutputStreamContainerModel;
import com.sun.codemodel.CodeWriter;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JFieldRef;
import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.writer.SingleStreamCodeWriter;
/**
 * Model holding all the JCodeModel objects in the container 
 * 
 * @author amir
 *
 */
public class CodeModelContainerModel implements OutputStreamContainerModel {
	private String containerClassName= CodeModelContainerBuilder.DEFAULT_CONTAINER_CLASS_NAME;
	private JCodeModel codeModel;
	private JDefinedClass appContainerClass;
	private JMethod startMethod;
	private final List<String> constructedBeanNames;
	private JMethod constructAll;
	private JDefinedClass beanHolderClass;
	private JFieldVar beanHolderField;

	public CodeModelContainerModel() {
		this.constructedBeanNames = new ArrayList<String>();
		this.codeModel= new JCodeModel();
	}

	public String getOutput() throws IOException {
		ByteArrayOutputStream baos= new ByteArrayOutputStream();
		this.outputToStream(baos);
		return baos.toString();
	}
	
	@Override
	public void outputToStream(OutputStream os) throws IOException {
		//precede first line with comment!!
		byte[] b= "//".getBytes();
		//ByteArrayOutputStream baos= new ByteArrayOutputStream();
		os.write(b, 0, 2);
		CodeWriter out= new SingleStreamCodeWriter(os);
		this.codeModel.build(out);
		//return baos.toString();
	}

	public JCodeModel getCodeModel() {
		return this.codeModel;
	}

	public void setCodeModel(JCodeModel codeModel) {
		this.codeModel = codeModel;
	}

	public JDefinedClass getAppContainerClass() {
		return this.appContainerClass;
	}

	public void setAppContainerClass(JDefinedClass appContainerClass) {
		this.appContainerClass = appContainerClass;
	}

	public JMethod getStartMethod() {
		return this.startMethod;
	}

	public void setStartMethod(JMethod startMethod) {
		this.startMethod = startMethod;
	}

	public JMethod getConstructAll() {
		return this.constructAll;
	}

	public void setConstructAll(JMethod constructAll) {
		this.constructAll = constructAll;
	}

	public JDefinedClass getBeanHolderClass() {
		return this.beanHolderClass;
	}

	public void setBeanHolderClass(JDefinedClass beanHolderClass) {
		this.beanHolderClass = beanHolderClass;
	}

	public JFieldVar getBeanHolderField() {
		return this.beanHolderField;
	}

	public void setBeanHolderField(JFieldVar beanHolderField) {
		this.beanHolderField = beanHolderField;
	}

	public String getContainerClassName() {
		return this.containerClassName;
	}

	public List<String> getConstructedBeanNames() {
		return this.constructedBeanNames;
	}
	

	public JFieldRef getBeanAsJFieldRef(String beanDefinitionName) {
		JFieldRef beanRef = this.getBeanHolderField().ref(CodeModelUtil.legaliseMemberName(beanDefinitionName));
		return beanRef;
	}

	public void setContainerClassName(String containerClassName) {
		this.containerClassName = containerClassName;
	}
}